/* 
 * Copyright 2011 kOSMik.
 * This file is part of kOSMik.
 * 
 * kOSMik is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * kOSMik is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with kOSMik.  If not, see <http://www.gnu.org/licenses/>.
 *  
 * kOSMik:
 * Open Street Map - Editor.
 * http://code.google.com/p/swp-dv-ws2010-osm-2/
 */

package de.fuberlin.kosmik.data;

import java.util.Collection;
import java.util.List;
import java.util.Map;

import android.os.Bundle;
import de.fuberlin.kosmik.data.dao.Poi;
import de.fuberlin.kosmik.data.dao.Point;
import de.fuberlin.kosmik.data.dao.TrackData;
import de.fuberlin.kosmik.data.dao.TrackRecord;
import de.fuberlin.kosmik.data.dao.Way;

/**
 * This interface declares the methods that the TrackRecorders calls to store
 * the acquired information to the data base.
 */
public interface DataBaseConnector {

	/**
	 * Create new track in DB.
	 * 
	 * @param name - name of track
	 * @param timestamp - the timestamp of the track (typically now)
	 * @return the unique id of the newly created tuple.
	 */
	long addTrack(String name, long timestamp);

	/**
	 * @param trackId - the data base ID of the way wanted
	 * @return - a list with lng's in even positions, starting with position
	 *         zero, and the matching lat's in non-even position, starting with
	 *         position one. @ - in case of communication failure with the data
	 *         base
	 */
	List<Double> getCoordinatesFromTrack(long trackId);

	/**
	 * Add point to given track.
	 * 
	 * @param longitude - longitude
	 * @param latitude - latitude
	 * @param timestamp timestamp in POSIX form
	 * @param trackId id of the track
	 * @return the unique id of the newly created tuple. @ if the arguments are
	 *         illegal
	 */
	long addPoint(double longitude, double latitude, long timestamp, long trackId);

	/**
	 * Insert a new POI with a reference (FK) to the given point. Each
	 * Key-Value-Pair of the tags-Bundle has to be inserted into the poi_value
	 * table.
	 * 
	 * @param pointId point id as saved in the database
	 * @param tags bundle which contains all tags which are related to point of
	 *            interest @ if the arguments are illegal
	 */
	void addPoi(long pointId, Bundle tags);

	/**
	 * Insert a new way. Each Key-Value-Pair of the tags-Bundle has to be
	 * inserted into the way_value table.
	 * 
	 * @param tags tags bundle to be saved with the point of interest
	 * @param isArea true if this way describes an area
	 * @return id of the created way @ if the arguments are illegal
	 */
	long startWay(Bundle tags, boolean isArea);

	/**
	 * Find all points of a certain way.
	 * 
	 * @param wayId - the data base ID of the way wanted
	 * @return - a list with lng's in even positions, starting with position
	 *         zero, and the matching lat's in non-even position, starting with
	 *         position one. @ when a communication failure occurs
	 */

	List<Point> getPointsFromWay(long wayId);

	/**
	 * Gets the database id's for a given track;
	 * @param trackId Database track Id
	 * @return a Collection of wayId's
	 */
	public Collection<Long> getWayIdsOfTrack(long trackId);
	/**
	 * Adds the given point to the given way or an area.
	 * 
	 * @param pointId data base id of the point
	 * @param wayId data base id of the way @ in case of communication failure
	 *            with the data base
	 */
	void addPointToWay(long pointId, long wayId);

	/**
	 * Associate the given media with the given point.
	 * 
	 * @param format media-type: text/image/audio/video
	 * @param content contentURI of the data type or the data itself if format
	 *            is text
	 * @param pointId the database id of the point @ if the arguments are
	 *            illegal
	 */
	void addMedia(String format, String content, long pointId);

	/**
	 * Will return a map from id to name of all tracks in the data base.
	 * 
	 * @return - map from id to name
	 */
	Map<Long, String> getAllTracks();

	/**
	 * Query all tracks stored in the data base.
	 * 
	 * @param startTimeStamp POSIX time after which tracks shall be returned
	 * @param endTimeStamp POSIX time until which tracks shall be returned
	 * @return a list track records that matches the interval
	 */
	/*
	 * as return type Vector is used instead of an array cause we use a cursor
	 * -> don't know the count of elements at beginning)
	 */
	Collection<TrackRecord> getAllTracksInTimeWindow(long startTimeStamp, long endTimeStamp);

	/**
	 * Searching the data base for all POIs of a given track, create their DAO
	 * objects and gives them back.
	 * 
	 * @param trackId - the track id of which the POIs are wanted
	 * @return - Collection of all Poi objects with their attributes as a bundle
	 */
	Collection<Poi> getPoisFromTrack(long trackId);

	/**
	 * @param trackId data base id of the track.
	 * @return all points of the given track as Point object
	 */
	Collection<Point> getPointsFromTrack(long trackId);

	/**
	 * Remove a point of interest from the data base.
	 * 
	 * @param poiId - id of POI to be removed
	 */
	void removePoi(long poiId);

	/**
	 * Set or change the track name.
	 * 
	 * @param trackId database id of the track.
	 * @param newName the new name which should be saved
	 */
	void setTrackName(long trackId, String newName);

	/**
	 * This method queries its data source and gives back a DataTrack object
	 * which contains the points of the track, as well as their distribution
	 * into ways.
	 * 
	 * @param trackId - id of track which should be queried
	 * @return TrackData object with all the relevant data
	 */
	TrackData getTrackData(long trackId);

	/**
	 * Removes a track, as well as all the tables related to it.
	 * 
	 * @param trackId - track to be removed
	 * @return true if the track and all its dependent entities were removed
	 *         from the data base
	 */
	boolean removeTrack(long trackId);

	/**
	 * Get track data like id, name and date added in a record.
	 * 
	 * @param trackId the id of the track you look for
	 * @return id, name and date added in a TrackRecord-structure or null, if
	 *         trackId does not exists in database
	 */
	TrackRecord getTrackById(long trackId);

	/**
	 * Get track data like id, name and date added in a record.
	 * 
	 * @return id, name and date added in a TrackRecord-structure, or null, if
	 *         trackId does not exists in database
	 */
	String[] getAllTrackNames();

	/**
	 * Returns a Collection of {@link Way} objects of all ways which were
	 * recorded in the given track of <code>trackId</code>.
	 * 
	 * @param trackId data base id of the wanted track
	 * @return Collection of Way objects
	 */
	Collection<Way> getWaysByTrack(long trackId);

	/**
	 * Close the underlying data base connection.
	 */
	void close();

	/**
	 * Checks whether this way is entered as a closed area in the data base.
	 * 
	 * @param wayId the data base ID of the way to be queried
	 * @return true if the way is an area, false otherwise.
	 */
	boolean isArea(long wayId);

	/**
	 * Receive the saved database name for a given track id.
	 * 
	 * @param trackId - data base Id of the track
	 * @return String of the name, or null if no track is found to this id.
	 */
	String getNameFromTrack(long trackId);

	/**
	 * Removes all Key-Value extras which are related to the given
	 * Poi-Id and replaces them with the new KV entries which are
	 * supplied.
	 *
	 * @param poiId Database ID of the Poi to be cleared of extra info
	 * @param values {@link Bundle} with the new values.
	 * @return true if succeeded, false otherwise.
	 */
	boolean setPoiValues(long poiId, Bundle values);

	/**
	 * Removes all Key-Value extras which are related to the given
	 * Way-Id and replaces them with the new KV entries which are
	 * supplied.
	 *
	 * @param wayId Database ID of the way to be updated
	 * @param values {@link Bundle} which contains the new values
	 * @return true if succedded, false otherwise.
	 */
	boolean setWayValues(long wayId, Bundle values);

	/**
	 * Removes the way-point relation from the data base
	 * as well as the way entity. It DOES NOT remove the
	 * points which stay a part of the track.
	 *
	 * @param wayId Database ID of the way to be removed
	 * @return true when succeeded, false otherwise.
	 */
	boolean removeWay(long wayId);

	/**
	 * Makes sure the connection is open, or created a new one.
	 */
	void reopen();
}
